package com.gopay.bis.pab.bcdl.operation;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.UnknownHostException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gopay.common.Result;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.exception.GopayException;

public class PabBcdlTransport {
	
	private final Logger logger = LoggerFactory.getLogger(PabBcdlTransport.class);
	private String onlineProxyHost;
	private String onlineProxyPort;
	private String onlineTimeOut;
	private String messageEncoding;
	
	/**
	 * 
	 * @param request
	 * @return 处理结果
	 */
	public Object submit(Object request) throws GopayException{
		Result r = new Result();
		Socket socket = null;
		OutputStream out = null;
		InputStream in = null;
		try {
			logger.error("pab request: " + request);
			socket = new Socket(onlineProxyHost,Integer.parseInt(onlineProxyPort));
			socket.setSendBufferSize(4096);
			socket.setTcpNoDelay(true);
			socket.setSoTimeout(Integer.parseInt(onlineTimeOut));
			socket.setKeepAlive(true);
			out = socket.getOutputStream();
			in = socket.getInputStream();
			out.write(((String) request).getBytes(messageEncoding));
			out.flush();
			int lengthHeadLen = 222;// 文件头长度
			int lengthBodyLenStartposi = 30;// 报文体长度域索引
			int lengthBodyLen = 10;// 报文体长度域长度
			int contentLength = 0;// 报文体长度
			byte[] lenHeadBuf = new byte[lengthHeadLen];
			in.read(lenHeadBuf, 0, lengthHeadLen);
			// 获取报文头中的长度字段
			contentLength = Integer.parseInt(new String(lenHeadBuf,lengthBodyLenStartposi, lengthBodyLen).trim());
			byte[] contentBuf = new byte[contentLength];
			in.read(contentBuf, 0, contentLength);
			byte[] resbyte = new byte[lengthHeadLen + contentLength];
			System.arraycopy(lenHeadBuf, 0, resbyte, 0, lenHeadBuf.length);
			System.arraycopy(contentBuf, 0, resbyte, lenHeadBuf.length, contentBuf.length);
			r.setDefaultModel(resbyte);
			r.setSuccess(true);
			r.setResultCode(ProcCodeConstants.PROC_CODE_100S1000);
			logger.error("pab response: " + getContent((byte[])r.getDefaultModel()));
		} catch (java.net.SocketTimeoutException e) {
			logger.error("(PAB)SDB银企直连socket超时，Exception：", e);
			r.setSuccess(false);
			r.setResultCode(ProcCodeConstants.PROC_CODE_100F3002);
			throw new GopayException(ProcCodeConstants.PROC_CODE_100E6047);
		} catch (UnknownHostException e) {
			logger.error("(PAB)SDB银企直连UnknownHostException：", e);
			r.setSuccess(false);
			r.setResultCode(ProcCodeConstants.PROC_CODE_100F3002);
			throw new GopayException(ProcCodeConstants.PROC_CODE_100E6047);
		} catch (Exception e) {
			logger.error("(PAB)SDB银企直连IOException：", e);
			r.setSuccess(false);
			r.setResultCode(ProcCodeConstants.PROC_CODE_100F1002);
			throw new GopayException(ProcCodeConstants.PROC_CODE_100E6047);
		} finally {
			closeStream(in, out, socket);
		}
		return r;
	}
	
	/**
	 * 
	 * @param bs
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	private String getContent(byte[] bs) throws UnsupportedEncodingException{
		return new String(bs, messageEncoding);
	}
	
	/**
	 * 关闭流及socket
	 * 
	 * @param in
	 * @param out
	 * @param socket
	 */
	private void closeStream(InputStream in, OutputStream out, Socket socket) {
		try {
			if (in != null) {
				in.close();
			}
			if (out != null) {
				out.close();
			}
			if (socket != null) {
				socket.close();
			}
		} catch (IOException e) {
			logger.error("", e);
		}
	}
}
